package service

import (
	"context"
	"fmt"
	"log"
	"strconv"
	"time"

	"gitee.com/wangshh_123/cross-pay-go/src/database"
	"gitee.com/wangshh_123/cross-pay-go/src/models"
	platformCommon "gitee.com/wangshh_123/cross-pay-go/src/platform/common"
	"gitee.com/wangshh_123/cross-pay-go/src/platform/integration"

	"github.com/shopspring/decimal"
	"gorm.io/gorm"
)

// BatchCardService 批量开卡服务
type BatchCardService struct {
	db              *gorm.DB
	platformManager *integration.PlatformManager
}

// NewBatchCardService 创建批量开卡服务实例
func NewBatchCardService(platformManager *integration.PlatformManager) *BatchCardService {
	return &BatchCardService{
		db:              database.DB,
		platformManager: platformManager,
	}
}

// BatchOpenCardRequest 批量开卡请求
type BatchOpenCardRequest struct {
	AccountId            string  `json:"accountId" binding:"omitempty"`
	Bin                  string  `json:"bin" binding:"omitempty"`
	CardBin              string  `json:"cardBin" binding:"omitempty"`
	CardBinId            string  `json:"cardBinId" binding:"omitempty"`
	CardholderId         string  `json:"cardholderId" binding:"required"`
	CardCurrency         string  `json:"cardCurrency" binding:"required"`
	CardExpirationDate   int     `json:"cardExpirationDate" binding:"required"`
	CardScheme           string  `json:"cardScheme" binding:"required"`
	CardType             string  `json:"cardType" binding:"required"`
	CardFormFactor       string  `json:"cardFormFactor" binding:"required"`
	RechargeAmount       string  `json:"rechargeAmount" binding:"omitempty"`
	Cost                 float64 `json:"cost" binding:"omitempty"`
	TransactionLimitType string  `json:"transactionLimitType" binding:"omitempty"`
	Nickname             string  `json:"nickname"`
	CardCount            int     `json:"cardCount" binding:"required,min=1,max=10"`
	TimeoutSeconds       int     `json:"timeoutSeconds" binding:"omitempty,min=5,max=60"`
	BatchId              string  `json:"batchId" binding:"required"`
}

// BatchOpenCardResult 批量开卡结果
type BatchOpenCardResult struct {
	BatchID      string       `json:"batchId"`
	Status       string       `json:"status"`
	CardCount    int          `json:"cardCount"`
	SuccessCount int          `json:"successCount"`
	FailedCount  int          `json:"failedCount"`
	CreatedAt    time.Time    `json:"createdAt"`
	CompletedAt  *time.Time   `json:"completedAt"`
	CardResults  []CardResult `json:"cardResults,omitempty"`
}

// CardResult 单卡开卡结果
type CardResult struct {
	Index        int    `json:"index"`
	RequestID    string `json:"requestId"`
	Nickname     string `json:"nickname"`
	Status       string `json:"status"`
	CardID       string `json:"cardId,omitempty"`
	Error        string `json:"error,omitempty"`
	ErrorCode    string `json:"errorCode,omitempty"`
	ErrorMessage string `json:"errorMessage,omitempty"`
}

// UserRoleBalance 用户角色和余额信息
type UserRoleBalance struct {
	RoleID  int64           `json:"roleId"`
	UserID  int64           `json:"userId"`
	Balance decimal.Decimal `json:"balance"`
}

// ProcessBatchOpenCard 处理批量开卡
func (s *BatchCardService) ProcessBatchOpenCard(ctx context.Context, req *BatchOpenCardRequest, userInfo *UserRoleBalance, matrixAccountInfo *models.UserMatrixAccount, platformType string) (*BatchOpenCardResult, error) {
	log.Printf("[BatchCardService] 开始处理批量开卡 - 批次ID: %s, 开卡数量: %d, 平台: %s", req.BatchId, req.CardCount, platformType)

	// 1. 创建批量开卡记录
	batchRecord, err := s.createBatchRecord(req, userInfo, matrixAccountInfo, platformType)
	if err != nil {
		return nil, fmt.Errorf("创建批量开卡记录失败: %v", err)
	}

	// 2. 预检查余额
	if err := s.preCheckBalance(req, userInfo, platformType); err != nil {
		// 更新记录状态为失败
		s.updateBatchRecordStatus(batchRecord.ID, "failed", 0, req.CardCount)
		return nil, fmt.Errorf("余额预检查失败: %v", err)
	}

	// 3. 异步处理批量开卡
	go s.processBatchOpenCardAsync(req, userInfo, matrixAccountInfo, platformType, batchRecord.ID)

	// 4. 返回初始结果
	return &BatchOpenCardResult{
		BatchID:      req.BatchId,
		Status:       "processing",
		CardCount:    req.CardCount,
		SuccessCount: 0,
		FailedCount:  0,
		CreatedAt:    batchRecord.CreatedAt,
	}, nil
}

// preCheckBalance 预检查余额
func (s *BatchCardService) preCheckBalance(req *BatchOpenCardRequest, userInfo *UserRoleBalance, platformType string) error {
	// 计算总充值金额
	var totalAmount decimal.Decimal
	if req.Cost > 0 {
		totalAmount = decimal.NewFromFloat(req.Cost).Mul(decimal.NewFromInt(int64(req.CardCount)))
	} else if req.RechargeAmount != "" {
		if amount, err := decimal.NewFromString(req.RechargeAmount); err == nil {
			totalAmount = amount.Mul(decimal.NewFromInt(int64(req.CardCount)))
		} else {
			return fmt.Errorf("无效的充值金额格式: %s", req.RechargeAmount)
		}
	}

	if totalAmount.IsZero() {
		log.Printf("[BatchCardService] 无充值金额，跳过余额检查")
		return nil
	}

	log.Printf("[BatchCardService] 预检查余额 - 总金额: %s, 开卡数量: %d", totalAmount.String(), req.CardCount)

	// 根据平台类型检查余额
	switch platformType {
	case "photonpay":
		return s.checkPhotonPayBalance(userInfo, totalAmount)
	case "hlpay":
		return s.checkHlPayBalance(userInfo, totalAmount)
	default:
		return fmt.Errorf("不支持的平台类型: %s", platformType)
	}
}

// checkPhotonPayBalance 检查PhotonPay平台余额
func (s *BatchCardService) checkPhotonPayBalance(userInfo *UserRoleBalance, totalAmount decimal.Decimal) error {
	// 根据用户角色检查相应的余额
	switch userInfo.RoleID {
	case 2: // 普通用户 - 不检查余额
		log.Printf("[BatchCardService] 普通用户，跳过余额检查")
		return nil
	case 3: // 主账号
		if userInfo.Balance.LessThan(totalAmount) {
			return fmt.Errorf("主账号余额不足: %s < %s", userInfo.Balance.String(), totalAmount.String())
		}
		log.Printf("[BatchCardService] 主账号余额检查通过: %s >= %s", userInfo.Balance.String(), totalAmount.String())
	case 5: // 子账号
		if userInfo.Balance.LessThan(totalAmount) {
			return fmt.Errorf("子账号余额不足: %s < %s", userInfo.Balance.String(), totalAmount.String())
		}
		log.Printf("[BatchCardService] 子账号余额检查通过: %s >= %s", userInfo.Balance.String(), totalAmount.String())
	default:
		return fmt.Errorf("不支持的用户角色: %d", userInfo.RoleID)
	}

	return nil
}

// checkHlPayBalance 检查HlPay平台余额
func (s *BatchCardService) checkHlPayBalance(userInfo *UserRoleBalance, totalAmount decimal.Decimal) error {
	// HlPay平台的余额检查逻辑
	// 这里可以根据需要实现HlPay特定的余额检查
	log.Printf("[BatchCardService] HlPay平台余额检查 - 用户ID: %d, 角色ID: %d, 总金额: %s", userInfo.UserID, userInfo.RoleID, totalAmount.String())
	return nil
}

// createBatchRecord 创建批量开卡记录
func (s *BatchCardService) createBatchRecord(req *BatchOpenCardRequest, userInfo *UserRoleBalance, matrixAccountInfo *models.UserMatrixAccount, platformType string) (*models.BatchCardOpenRecord, error) {
	// 优先使用bin字段，如果没有则使用cardBin字段
	cardBin := req.Bin
	if cardBin == "" {
		cardBin = req.CardBin
	}

	batchRecord := &models.BatchCardOpenRecord{
		BatchID:        req.BatchId,
		UserID:         userInfo.UserID,
		MatrixAccount:  matrixAccountInfo.MatrixAccount,
		Platform:       platformType,
		CardCount:      req.CardCount,
		CardScheme:     req.CardScheme,
		CardType:       req.CardType,
		CardFormFactor: req.CardFormFactor,
		CardBin:        cardBin,
		CardCurrency:   req.CardCurrency,
		RechargeAmount: req.RechargeAmount,
		Cost:           req.Cost,
		Status:         "processing",
		SuccessCount:   0,
		FailedCount:    0,
		CreatedAt:      time.Now(),
	}

	if err := s.db.Create(batchRecord).Error; err != nil {
		return nil, fmt.Errorf("创建批量开卡记录失败: %v", err)
	}

	log.Printf("[BatchCardService] 批量开卡记录创建成功 - 记录ID: %d", batchRecord.ID)
	return batchRecord, nil
}

// processBatchOpenCardAsync 异步处理批量开卡
func (s *BatchCardService) processBatchOpenCardAsync(req *BatchOpenCardRequest, userInfo *UserRoleBalance, matrixAccountInfo *models.UserMatrixAccount, platformType string, batchRecordID int64) {
	log.Printf("[BatchCardService] 开始异步处理批量开卡 - 批次ID: %s, 记录ID: %d", req.BatchId, batchRecordID)

	successCount := 0
	failedCount := 0
	var cardResults []CardResult

	// 优先使用bin字段，如果没有则使用cardBin字段
	cardBin := req.Bin
	if cardBin == "" {
		cardBin = req.CardBin
	}

	// 处理充值金额
	var rechargeAmountStr string
	var rechargeAmountFloat float64

	if req.Cost > 0 {
		rechargeAmountStr = fmt.Sprintf("%.2f", req.Cost)
		rechargeAmountFloat = req.Cost
	} else if req.RechargeAmount != "" {
		rechargeAmountStr = req.RechargeAmount
		if amount, err := strconv.ParseFloat(req.RechargeAmount, 64); err == nil {
			rechargeAmountFloat = amount
		}
	}

	// 逐个处理每张卡的开卡
	for i := 0; i < req.CardCount; i++ {
		// 生成唯一的请求ID
		requestID := fmt.Sprintf("%s_%d_%d", req.BatchId, time.Now().UnixNano(), i)

		// 生成卡片昵称（如果提供了基础昵称）
		cardNickname := req.Nickname
		if cardNickname != "" && req.CardCount > 1 {
			cardNickname = fmt.Sprintf("%s_%d", req.Nickname, i+1)
		}

		log.Printf("[BatchCardService] 处理第 %d/%d 张卡 - 请求ID: %s", i+1, req.CardCount, requestID)

		// 构建单卡开卡请求
		openCardRequest := &platformCommon.OpenCardRequest{
			UserID:               userInfo.UserID,
			MatrixAccount:        matrixAccountInfo.MatrixAccount,
			AccountID:            req.AccountId,
			CardBin:              cardBin,
			CardBinId:            req.CardBinId,
			CardholderID:         req.CardholderId,
			CardCurrency:         req.CardCurrency,
			CardExpirationDate:   req.CardExpirationDate,
			CardScheme:           req.CardScheme,
			CardType:             req.CardType,
			CardFormFactor:       req.CardFormFactor,
			Cost:                 req.Cost,
			RechargeAmount:       rechargeAmountStr,
			RequestID:            requestID,
			TransactionLimitType: req.TransactionLimitType,
		}

		// 创建上下文
		ctx := context.Background()
		ctx = context.WithValue(ctx, "user_id", userInfo.UserID)
		ctx = context.WithValue(ctx, "matrix_account_info", matrixAccountInfo)

		// 调用平台管理器处理单卡开卡
		result, err := s.platformManager.HandleOpenCard(ctx, platformType, openCardRequest)

		cardResult := CardResult{
			Index:     i + 1,
			RequestID: requestID,
			Nickname:  cardNickname,
		}

		if err != nil {
			log.Printf("[BatchCardService] 第 %d 张卡开卡失败: %v", i+1, err)
			failedCount++
			cardResult.Status = "failed"
			cardResult.Error = err.Error()

			// 处理平台错误
			if platformErr, ok := err.(*integration.PlatformError); ok {
				cardResult.ErrorCode = platformErr.Code
				cardResult.ErrorMessage = platformErr.Message
			}
		} else {
			log.Printf("[BatchCardService] 第 %d 张卡开卡成功: %+v", i+1, result)
			successCount++
			cardResult.Status = "success"

			// 保存卡片信息到数据库
			if result.Code == "0000" {
				cardID := result.Data
				if cardID != "" {
					s.saveCardToDatabase(cardID, userInfo.UserID, platformType, cardNickname, rechargeAmountFloat, cardBin)
					cardResult.CardID = cardID
				}
			}
		}

		cardResults = append(cardResults, cardResult)

		// 添加延迟，避免请求过于频繁
		if i < req.CardCount-1 {
			time.Sleep(100 * time.Millisecond)
		}
	}

	// 更新批量开卡记录
	s.updateBatchRecordStatus(batchRecordID, "completed", successCount, failedCount)

	// 记录详细结果到日志
	log.Printf("[BatchCardService] 批量开卡完成 - 批次ID: %s, 总数: %d, 成功: %d, 失败: %d",
		req.BatchId, req.CardCount, successCount, failedCount)

	for _, result := range cardResults {
		log.Printf("[BatchCardService] 卡片结果: %+v", result)
	}
}

// saveCardToDatabase 保存卡片信息到数据库
func (s *BatchCardService) saveCardToDatabase(cardID string, userID int64, platform string, nickname string, rechargeAmount float64, cardBin string) {
	// 检查卡片是否已存在
	var existingCard models.UserCard
	if err := s.db.Where("card_id = ?", cardID).First(&existingCard).Error; err == nil {
		// 卡片已存在，更新昵称、CardBin和充值金额
		updates := map[string]interface{}{
			"nike_name": nickname,
		}

		// 如果提供了CardBin，则更新
		if cardBin != "" {
			updates["card_bin"] = cardBin
		}

		// 累加充值金额到现有的TotalTransferAmount
		if rechargeAmount > 0 && platform != "photonpay" {
			rechargeAmountStr := fmt.Sprintf("%.2f", rechargeAmount)
			rechargeAmountDecimal, err := decimal.NewFromString(rechargeAmountStr)
			if err != nil {
				log.Printf("[BatchCardService] 金额转换失败: %v", err)
				rechargeAmountDecimal = decimal.NewFromFloat(rechargeAmount)
			}
			updates["TotalTransferAmount"] = existingCard.TotalTransferAmount.Add(rechargeAmountDecimal)
		}

		// 更新卡片信息
		if err := s.db.Model(&existingCard).Updates(updates).Error; err != nil {
			log.Printf("[BatchCardService] 更新现有卡片失败: CardID=%s, 错误: %v", cardID, err)
		} else {
			log.Printf("[BatchCardService] 更新现有卡片: CardID=%s, CardBin=%s, 昵称=%s", cardID, cardBin, nickname)
		}
	} else {
		// 创建新卡片记录
		var totalTransferAmount decimal.Decimal
		if rechargeAmount > 0 && platform != "photonpay" {
			rechargeAmountStr := fmt.Sprintf("%.2f", rechargeAmount)
			if amountDecimal, err := decimal.NewFromString(rechargeAmountStr); err == nil {
				totalTransferAmount = amountDecimal
			} else {
				totalTransferAmount = decimal.NewFromFloat(rechargeAmount)
			}
		} else {
			totalTransferAmount = decimal.Zero
		}

		newCard := models.UserCard{
			UserID:              userID,
			CardID:              cardID,
			Platform:            platform,
			CardStatus:          "normal",
			CardBin:             cardBin,
			NikeName:            nickname,
			TotalTransferAmount: totalTransferAmount,
			CardType:            "recharge",
		}

		if err := s.db.Create(&newCard).Error; err != nil {
			log.Printf("[BatchCardService] 创建新卡片失败: CardID=%s, 错误: %v", cardID, err)
		} else {
			log.Printf("[BatchCardService] 创建新卡片: CardID=%s, CardBin=%s, 昵称=%s", cardID, cardBin, nickname)
		}
	}
}

// updateBatchRecordStatus 更新批量开卡记录状态
func (s *BatchCardService) updateBatchRecordStatus(batchRecordID int64, status string, successCount, failedCount int) {
	updates := map[string]interface{}{
		"status":        status,
		"success_count": successCount,
		"failed_count":  failedCount,
	}

	if status == "completed" {
		completedAt := time.Now()
		updates["completed_at"] = &completedAt
	}

	if err := s.db.Model(&models.BatchCardOpenRecord{}).Where("id = ?", batchRecordID).Updates(updates).Error; err != nil {
		log.Printf("[BatchCardService] 更新批量开卡记录失败: %v", err)
	} else {
		log.Printf("[BatchCardService] 批量开卡记录更新成功 - 记录ID: %d, 状态: %s, 成功: %d, 失败: %d", batchRecordID, status, successCount, failedCount)
	}
}

// GetBatchOpenCardStatus 获取批量开卡状态
func (s *BatchCardService) GetBatchOpenCardStatus(batchID string) (*BatchOpenCardResult, error) {
	var batchRecord models.BatchCardOpenRecord
	if err := s.db.Where("batch_id = ?", batchID).First(&batchRecord).Error; err != nil {
		return nil, fmt.Errorf("批量开卡记录不存在: %s", batchID)
	}

	return &BatchOpenCardResult{
		BatchID:      batchRecord.BatchID,
		Status:       batchRecord.Status,
		CardCount:    batchRecord.CardCount,
		SuccessCount: batchRecord.SuccessCount,
		FailedCount:  batchRecord.FailedCount,
		CreatedAt:    batchRecord.CreatedAt,
		CompletedAt:  batchRecord.CompletedAt,
	}, nil
}
